#ifndef SPI_HPP
#define SPI_HPP

#include <cstddef>

class SPIMaster {
public:
    enum class ClockPolarity {
        Low,
        High,
    };

    enum class ClockPhase {
        LeadingEdge,
        TrailingEdge,
    };

    enum class Event : unsigned int {
        TransmitComplete,
        DataReceived,
        ErrorOccurred,
    };

public:
    virtual ~SPIMaster() = default;

    virtual bool open(void) = 0;
    virtual bool close(void) = 0;
    virtual size_t transmit(void *tx_buffer,void *rx_buffer,size_t size) = 0;

    virtual bool setClockPolarity(ClockPolarity clock_polarity) = 0;
    virtual ClockPolarity getClockPolarity(void) = 0;
    virtual bool setClockPhase(void) = 0;
    virtual ClockPhase getClockPhase(void) = 0;
    
    virtual bool addEventCallback(Event event,void (*callback)(void)) = 0;
    virtual bool removeEventCallback(Event event);

    virtual int getErrorNumber(void) = 0;
};

class SPIDevice {
public:
    enum class Event {
        TransmitComplete,
        DataReceived,
        ErrorOccurred,
    };

public:
    virtual ~SPIDevice() = default;

    virtual bool open(void) = 0;
    virtual bool close(void) = 0;
    virtual size_t transmit(void *tx_buffer,void *rx_buffer,size_t size) = 0;
    virtual bool setChipSelect(bool status) = 0;

    virtual bool attachBus(SPIMaster& master) = 0;
    virtual bool detachBus(void) = 0;

    virtual bool addEventCallback(Event event,void (*callback)(void)) = 0;
    virtual bool removeEventCallback(Event event) = 0;

    virtual int getErrorNumber(void) = 0;
};

#endif